﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Windows.Media.Imaging;

using System.IO.IsolatedStorage;
using System.IO;
using System.Windows.Media.Effects;


using System.Windows.Ink;

using GameEngine.Weather;

namespace GameEngine
{
    public partial class MainPage : UserControl
    {

        private Engine engine;
        private GameGrid screen;
        private PlayerCharacter player;

        private int _viewSizeX = 590, _viewSizeY = 390, _viewCenterX = 13, _viewCenterY = 4;
        private IntSize _tileSize = new IntSize(32,32);
        private IntSize _mapSize = new IntSize(30,300);

        private Spritesheet[] _robotSheet = new Spritesheet[8];
        private IntSize _robotSize = new IntSize(32, 48);
        private IntPoint _robotFeetOffset = new IntPoint(0, 20);

        private Spritesheet[] _femalePaladinSheet = new Spritesheet[8];
        private IntSize _femalePaladinSize = new IntSize(48, 48);
        private IntPoint _femalePaladinFeetOffset = new IntPoint(24, 20);

        private Spritesheet[] _redKnightSheet = new Spritesheet[8];
        private IntSize _redKnightSize = new IntSize(72, 72);
        private IntPoint _redKnightFeetOffset = new IntPoint(25, 35);

        private Spritesheet _tileAnimation;
        private Spritesheet _tileAnimation2;
        private Spritesheet _tileAnimation3;

        private bool _inMenu = true;


        public MainPage()
        {
            InitializeComponent();
            this.Loaded+=new RoutedEventHandler(MainPage_Loaded);
        }


        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            Application.Current.Host.Settings.EnableCacheVisualization = true;
            Application.Current.Host.Settings.EnableFrameRateCounter = true;
            Application.Current.Host.Settings.MaxFrameRate = 60;

            //SoundManager man = new SoundManager();
            //man.PlayLooped("Sounds/1.mp3", 1.0);

            this.engine = new Engine(map);

            //tileanimation
            _tileAnimation = new Spritesheet("Images/water_31.jpg", this._tileSize, 9, new IntPoint(0, 0), new IntPoint(3, 3));
            string[] source = new string[3];
            source[0] = "Images/water_31.jpg";
            source[1] = "Images/cave_bilevel.png";
            source[2] = "Images/Woodland_ground.png";
            _tileAnimation2 = new Spritesheet(source, this._tileSize);
            string[] source2 = new string[3];
            source2[0] = "Menu/CreditsButton.png";
            source2[1] = "Menu/CreditsButton.png";
            source2[2] = "Menu/CreditsButton.png";
            _tileAnimation3 = new Spritesheet(source2, this._tileSize);

            //LoadRobotSheet();
            //LoadFemalePaladinSheet();
            LoadRedKnightSheet();
        }


        private void LoadRedKnightSheet()
        {
            String[] sources = new String[9];

            for (int i = 0; i < 8; i++)
            {
                sources[i+1] = "Images/Player/reiner/redKnight/running n000" + i + ".png";
            }
            sources[0] = "Images/Player/reiner/redKnight/stopped0004.png";
            this._redKnightSheet[0] = new Spritesheet(sources, this._redKnightSize);

            for (int i = 0; i < 8; i++)
            {
                sources[i + 1] = "Images/Player/reiner/redKnight/running ne000" + i + ".png";
            }
            sources[0] = "Images/Player/reiner/redKnight/stopped0005.png";
            this._redKnightSheet[1] = new Spritesheet(sources, this._redKnightSize);

            for (int i = 0; i < 8; i++)
            {
                sources[i + 1] = "Images/Player/reiner/redKnight/running e000" + i + ".png";
            }
            sources[0] = "Images/Player/reiner/redKnight/stopped0006.png";
            this._redKnightSheet[2] = new Spritesheet(sources, this._redKnightSize);

            for (int i = 0; i < 8; i++)
            {
                sources[i + 1] = "Images/Player/reiner/redKnight/running se000" + i + ".png";
            }
            sources[0] = "Images/Player/reiner/redKnight/stopped0007.png";
            this._redKnightSheet[3] = new Spritesheet(sources, this._redKnightSize);

            for (int i = 0; i < 8; i++)
            {
                sources[i + 1] = "Images/Player/reiner/redKnight/running s000" + i + ".png";
            }
            sources[0] = "Images/Player/reiner/redKnight/stopped0000.png";
            this._redKnightSheet[4] = new Spritesheet(sources, this._redKnightSize);

            for (int i = 0; i < 8; i++)
            {
                sources[i + 1] = "Images/Player/reiner/redKnight/running sw000" + i + ".png";
            }
            sources[0] = "Images/Player/reiner/redKnight/stopped0001.png";
            this._redKnightSheet[5] = new Spritesheet(sources, this._redKnightSize);

            for (int i = 0; i < 8; i++)
            {
                sources[i + 1] = "Images/Player/reiner/redKnight/running w000" + i + ".png";
            }
            sources[0] = "Images/Player/reiner/redKnight/stopped0002.png";
            this._redKnightSheet[6] = new Spritesheet(sources, this._redKnightSize);

            for (int i = 0; i < 8; i++)
            {
                sources[i + 1] = "Images/Player/reiner/redKnight/running nw000" + i + ".png";
            }
            sources[0] = "Images/Player/reiner/redKnight/stopped0003.png";
            this._redKnightSheet[7] = new Spritesheet(sources, this._redKnightSize);
        }


        private void LoadRobotSheet()
        {
            //loads player animations
            //up
            this._robotSheet[0] = new Spritesheet("Images/Player/100.png", this._robotSize, 8, new IntPoint(0, 2), new IntPoint(8, 3));
            //down
            this._robotSheet[1] = new Spritesheet("Images/Player/100.png", this._robotSize, 8, new IntPoint(0, 0), new IntPoint(8, 1));
            //left
            this._robotSheet[2] = new Spritesheet("Images/Player/100.png", this._robotSize, 8, new IntPoint(0, 3), new IntPoint(8, 4));
            //left+up-same as left
            this._robotSheet[3] = new Spritesheet("Images/Player/100.png", this._robotSize, 8, new IntPoint(0, 3), new IntPoint(8, 4));
            //left+down-same as left
            this._robotSheet[4] = new Spritesheet("Images/Player/100.png", this._robotSize, 8, new IntPoint(0, 3), new IntPoint(8, 4));
            //right
            this._robotSheet[5] = new Spritesheet("Images/Player/100.png", this._robotSize, 8, new IntPoint(0, 1), new IntPoint(8, 2));
            //right+up-same as right
            this._robotSheet[6] = new Spritesheet("Images/Player/100.png", this._robotSize, 8, new IntPoint(0, 1), new IntPoint(8, 2));
            //right+down-same as right
            this._robotSheet[7] = new Spritesheet("Images/Player/100.png", this._robotSize, 8, new IntPoint(0, 1), new IntPoint(8, 2));
        }


        /// <summary>
        ///     Loads spritesheet for the players character. 
        /// </summary>
        private void LoadFemalePaladinSheet()
        {
            String[] sources = new String[16];

            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 16; j++)
                {
                    if (j < 10)
                        sources[j] = "Images/Player/inet/FemalePaladin/02_0" + (i + 1) +"_0" + j + ".png";
                    else
                        sources[j] = "Images/Player/inet/FemalePaladin/02_0" + (i + 1) + "_" + j + ".png";
                }
                this._femalePaladinSheet[i] = new Spritesheet(sources, this._femalePaladinSize);
            }         
        }


        void MainPage_KeyDown(object sender, KeyEventArgs e)
        {
            {
                if (this.screen != null)
                {
                    switch (e.Key)
                    {
                        case Key.Left: _viewCenterX -= 1; break;    //To the left
                        case Key.Right: _viewCenterX += 1; break;   //To the right
                        case Key.Up: _viewCenterY -= 1; break;      //To the up
                        case Key.Down: _viewCenterY += 1; break;    //To the low
                        case Key.Escape:
                            {
                                if (!_inMenu)
                                {
                                    ShowMenu();
                                }
                                else 
                                {
                                    Resume();
                                }
                            }
                            break;
                    }

                    /*if (_viewCenterX < 0)
                        _viewCenterX = 0;
                    if (_viewCenterY < 0)
                        _viewCenterY = 0;

                    Viewport port = new Viewport(new IntPoint(_viewCenterX, _viewCenterY), _tileSize, new IntSize(_viewSizeX, _viewSizeY));
                    this.screen.SetViewport(port);*/
                }
            }
        }


        private void ShowMenu()
        {
            this.engine.Stop();
            this.menuBackground.Visibility = System.Windows.Visibility.Visible;
            this.menu.Visibility = System.Windows.Visibility.Visible;
            _inMenu = true;
        }


        private void Resume()
        {
            this.engine.Run();
            this.menuBackground.Visibility = System.Windows.Visibility.Collapsed;
            this.menu.Visibility = System.Windows.Visibility.Collapsed;
            _inMenu = false;
        }


        private void OnSaveButtonClick(object sender, RoutedEventArgs e)
        {
            SaveFileDialog textDialog = new SaveFileDialog();
            textDialog.Filter = "Map Files | *.mp";
            textDialog.DefaultExt = "mp";

            bool? result = textDialog.ShowDialog();
            if (result == true)
            {
                System.IO.Stream fileStream = textDialog.OpenFile();
                this.screen.SaveMapToFile(fileStream);
            }
        }


        private void OnLoadMapClick(object sender, RoutedEventArgs e)
        {
            OpenFileDialog textDialog = new OpenFileDialog();
            textDialog.Filter = "Map Files | *.mp";

            bool? result = textDialog.ShowDialog();
            if (result == true)
            {
                FileInfo p = textDialog.File;
                FileStream fileStream = p.OpenRead();
                menu.Visibility = Visibility.Collapsed;
                menuBackground.Visibility = Visibility.Collapsed;
                this.screen  = GameGrid.LoadMapFromFile(fileStream);
                this.StartMap();
            }
        }


        /// <summary>
        ///     Attaches the recently loaded/created grid and starts the engine.
        ///     Attaches viewport. 
        ///     Sets click triggers for all tiles.
        ///     Sets keyboard handlers.
        ///     Hides editing tools.
        /// </summary>
        private void StartMap()
        {
            this._inMenu = false;

            this.engine.DetachActiveGrid();

            /*screen.SetTileAnimation(new IntPoint(1, 0), this._tileAnimation, 0.03);
            screen.SetTileAnimation(new IntPoint(2, 0), this._tileAnimation, 0.03);
            screen.SetTileAnimation(new IntPoint(1, 2), this._tileAnimation2, 0.03);
            screen.SetTileAnimation(new IntPoint(1, 3), this._tileAnimation2, 0.03);
            screen.SetTileAnimation(new IntPoint(0, 3), this._tileAnimation3, 0.3);
            screen.SetTileAnimation(new IntPoint(0, 5), this._tileAnimation3, 0.3);*/

            //SnowEffect weather = new SnowEffect(300, this.screen.BoardSizePixels, 30);
            //SnowEffect weather = new SnowEffect(800, new IntSize(this._viewSizeX, this._viewSizeY), 0);
           // screen.WeatherEffect = weather;

            this.engine.AttachGrid(this.screen);

            //IntPoint tile = new IntPoint();

            //Effect effect = new BlurEffect();
            //(effect as BlurEffect).Radius = 4;

            //this.screen.SetTileEffect(new Rect(0.0, 0.0, 20.0, 20.0), effect, TileLayers.foreground);

            Effect effect2 = new WeirdEffect();

            this.screen.SetTileEffect(new Rect(0.0, 0.0, 20.0, 20.0), effect2, TileLayers.foreground);

            //if we alrady have handler it removes it, if we dont it's OK
            this.KeyDown -= new KeyEventHandler(MainPage_KeyDown);
            this.KeyDown += new KeyEventHandler(MainPage_KeyDown);

            this.player = new PlayerCharacter();
            //this.player.Effect = effect;
            //this.player.PositionChanged += new PositionChangedHandler(player_PositionChanged);
            //this.player.SetVisual("Images/Player/red.png"); 
            //this.player.SetVisual("Images/Player/red.png");
            this.player.SetAnimation(this._redKnightSheet, 8);
            this.player.BaseOffset = this._redKnightFeetOffset;
            //sets the speed of the player
            this.player.Velocity = new IntPoint(100, 100);
            //adds the player to the gamegrid
            screen.AddGameObject(player, new IntPoint(0, 0), new IntPoint(0, 0));
            //screen.AddGameObject(player, new IntPoint(7, 299), new IntPoint(224, 9568));
            Viewport port = new Viewport(player, new IntSize(_viewSizeX, _viewSizeY));
            //Viewport port = new Viewport(new IntPoint(_viewCenterX, _viewCenterY), _tileSize, new IntSize(_viewSizeX, _viewSizeY));
            this.screen.SetViewport(port);

            this.screen.BackgroundColor = Colors.Black;

            this.engine.Run();
        }


        private void OnResumeClick(object sender, MouseButtonEventArgs e)
        {
            Resume();
        }
    }
}
